/*!
 * samaxesJS JavaScript Library
 * http://code.google.com/p/samaxesjs/
 *
 * Copyright (c) @YEAR samaxes.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @projectDescription samaxesJS JavaScript Library.
 * @author <a href="http://www.samaxes.com/">Samuel Santos</a>
 * @namespace samaxesJS
 * @type {Object}
 */
var samaxesJS = {
    /**
     * Crossbrowser DOMContentLoaded handling code.
     *
     * @param {function} handler The handler called when the ready event fires.
     */
    bindReady: function(handler){
        var called = false;

        function ready() {
            if (called) {
                return;
            }
            called = true;
            handler();
        }

        if (document.addEventListener) { // native event
            document.addEventListener('DOMContentLoaded', ready, false);
        } else if (document.attachEvent) { // IE
            try {
                var isFrame = window.frameElement != null;
            } catch(e) {
            }

            // IE, the document is not inside a frame
            if (document.documentElement.doScroll && !isFrame) {
                function tryScroll() {
                    if (called) {
                        return;
                    }
                    try {
                        document.documentElement.doScroll('left');
                        ready();
                    } catch(e) {
                        setTimeout(tryScroll, 20);
                    }
                }
                tryScroll();
            }

            // IE, the document is inside a frame
            document.attachEvent('onreadystatechange', function() {
                if (document.readyState === 'complete') {
                    ready();
                }
            });
        }

        // Old browsers
        if (window.addEventListener) {
            window.addEventListener('load', ready, false);
        } else if (window.attachEvent) {
            window.attachEvent('onload', ready);
        } else {
            var fn = window.onload; // very old browser, copy old onload
            window.onload = function() { // replace by new onload and call the old one
                fn && fn();
                ready();
            };
        }
    },
    /**
     * Trim whitespace.
     *
     * @param {String} str The String to trim.
     * @return {String} The trimmed string.
     */
    trim: function(str) {
        return (str || '').replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g, '');
    },
    /**
     * Gets the size of an associative array.
     *
     * @param {Object} obj Associative array to check size.
     * @return {Number} The size of the associative array.
     */
    size: function(obj) {
        var size = 0, key;

        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                size++;
            }
        }

        return size;
    },
    /**
     * Gets an element children filtered by tag name.
     *
     * @param {Object} parent The parent node element.
     * @param {String} name The tag name.
     * @return {Array} The element children.
     */
    getChildrenByTagName: function(parent, name) {
        var children = parent.children;
        var length = children.length;
        var filteredChildren = [];

        for (var i = 0; i < length; i++) {
            if (children[i].tagName.match(new RegExp(name, 'i'))) {
                filteredChildren.push(children[i]);
            }
        }

        return filteredChildren;
    }
};

